//+------------------------------------------------------------------+
//|                                                  TradeExecution.mqh |
//|                                  Copyright 2024, MetaQuotes Software |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, MetaQuotes Software"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

// 交易类型枚举
enum ENUM_TRADE_TYPE {
    TRADE_BUY,            // 买入
    TRADE_SELL,           // 卖出
    TRADE_CLOSE_BUY,      // 平多
    TRADE_CLOSE_SELL,     // 平空
    TRADE_MODIFY          // 修改
};

// 交易状态枚举
enum ENUM_TRADE_STATUS {
    TRADE_STATUS_PENDING,  // 等待执行
    TRADE_STATUS_EXECUTED, // 已执行
    TRADE_STATUS_FAILED,   // 执行失败
    TRADE_STATUS_CANCELLED // 已取消
};

// 交易结构
struct Trade {
    ENUM_TRADE_TYPE type;         // 交易类型
    double volume;                // 交易量
    double price;                 // 价格
    double stopLoss;              // 止损价
    double takeProfit;            // 止盈价
    string comment;               // 注释
    ENUM_TRADE_STATUS status;     // 交易状态
    ulong ticket;                 // 订单号
    datetime time;                // 交易时间
};

// 交易执行系统类
class CTradeExecution {
private:
    // 交易数组
    Trade trades[];
    
    // 交易参数
    double defaultVolume;         // 默认交易量
    double maxVolume;             // 最大交易量
    double minVolume;             // 最小交易量
    int maxSlippage;              // 最大滑点
    int maxRetries;               // 最大重试次数
    int retryDelay;               // 重试延迟
    
    // 初始化参数
    void InitializeParameters() {
        defaultVolume = 0.1;
        maxVolume = 10.0;
        minVolume = 0.01;
        maxSlippage = 3;
        maxRetries = 3;
        retryDelay = 1000;
    }
    
    // 检查交易量
    bool CheckVolume(double volume) {
        if(volume < minVolume || volume > maxVolume) {
            Print("交易量超出范围: ", volume);
            return false;
        }
        return true;
    }
    
    // 执行买入
    bool ExecuteBuy(Trade &trade) {
        if(!CheckVolume(trade.volume)) return false;
        
        for(int i = 0; i < maxRetries; i++) {
            trade.ticket = OrderSend(_Symbol, OP_BUY, trade.volume, trade.price,
                                   maxSlippage, trade.stopLoss, trade.takeProfit,
                                   trade.comment, 0, 0, clrGreen);
                                   
            if(trade.ticket > 0) {
                trade.status = TRADE_STATUS_EXECUTED;
                return true;
            }
            
            Sleep(retryDelay);
        }
        
        trade.status = TRADE_STATUS_FAILED;
        return false;
    }
    
    // 执行卖出
    bool ExecuteSell(Trade &trade) {
        if(!CheckVolume(trade.volume)) return false;
        
        for(int i = 0; i < maxRetries; i++) {
            trade.ticket = OrderSend(_Symbol, OP_SELL, trade.volume, trade.price,
                                   maxSlippage, trade.stopLoss, trade.takeProfit,
                                   trade.comment, 0, 0, clrRed);
                                   
            if(trade.ticket > 0) {
                trade.status = TRADE_STATUS_EXECUTED;
                return true;
            }
            
            Sleep(retryDelay);
        }
        
        trade.status = TRADE_STATUS_FAILED;
        return false;
    }
    
    // 执行平多
    bool ExecuteCloseBuy(Trade &trade) {
        for(int i = 0; i < maxRetries; i++) {
            if(OrderSelect(trade.ticket, SELECT_BY_TICKET)) {
                if(OrderType() == OP_BUY) {
                    if(OrderClose(OrderTicket(), OrderLots(), trade.price,
                                maxSlippage, clrBlue)) {
                        trade.status = TRADE_STATUS_EXECUTED;
                        return true;
                    }
                }
            }
            
            Sleep(retryDelay);
        }
        
        trade.status = TRADE_STATUS_FAILED;
        return false;
    }
    
    // 执行平空
    bool ExecuteCloseSell(Trade &trade) {
        for(int i = 0; i < maxRetries; i++) {
            if(OrderSelect(trade.ticket, SELECT_BY_TICKET)) {
                if(OrderType() == OP_SELL) {
                    if(OrderClose(OrderTicket(), OrderLots(), trade.price,
                                maxSlippage, clrBlue)) {
                        trade.status = TRADE_STATUS_EXECUTED;
                        return true;
                    }
                }
            }
            
            Sleep(retryDelay);
        }
        
        trade.status = TRADE_STATUS_FAILED;
        return false;
    }
    
    // 执行修改
    bool ExecuteModify(Trade &trade) {
        for(int i = 0; i < maxRetries; i++) {
            if(OrderSelect(trade.ticket, SELECT_BY_TICKET)) {
                if(OrderModify(OrderTicket(), OrderOpenPrice(),
                             trade.stopLoss, trade.takeProfit, 0, clrYellow)) {
                    trade.status = TRADE_STATUS_EXECUTED;
                    return true;
                }
            }
            
            Sleep(retryDelay);
        }
        
        trade.status = TRADE_STATUS_FAILED;
        return false;
    }
    
    // 添加交易
    void AddTrade(Trade &trade) {
        int size = ArraySize(trades);
        ArrayResize(trades, size + 1);
        trades[size] = trade;
    }
    
public:
    // 构造函数
    CTradeExecution() {
        InitializeParameters();
    }
    
    // 析构函数
    ~CTradeExecution() {
        ArrayFree(trades);
    }
    
    // 设置参数
    void SetParameters(double defaultVolume, double maxVolume, double minVolume,
                      int maxSlippage, int maxRetries, int retryDelay) {
        this.defaultVolume = defaultVolume;
        this.maxVolume = maxVolume;
        this.minVolume = minVolume;
        this.maxSlippage = maxSlippage;
        this.maxRetries = maxRetries;
        this.retryDelay = retryDelay;
    }
    
    // 执行交易
    bool ExecuteTrade(Trade &trade) {
        trade.time = TimeCurrent();
        trade.status = TRADE_STATUS_PENDING;
        
        bool result = false;
        switch(trade.type) {
            case TRADE_BUY:
                result = ExecuteBuy(trade);
                break;
            case TRADE_SELL:
                result = ExecuteSell(trade);
                break;
            case TRADE_CLOSE_BUY:
                result = ExecuteCloseBuy(trade);
                break;
            case TRADE_CLOSE_SELL:
                result = ExecuteCloseSell(trade);
                break;
            case TRADE_MODIFY:
                result = ExecuteModify(trade);
                break;
        }
        
        if(result) {
            AddTrade(trade);
        }
        
        return result;
    }
    
    // 获取交易历史
    int GetTradeHistory(Trade &history[]) {
        int size = ArraySize(trades);
        ArrayResize(history, size);
        ArrayCopy(history, trades);
        return size;
    }
    
    // 获取特定状态的交易
    int GetTradesByStatus(ENUM_TRADE_STATUS status, Trade &filteredTrades[]) {
        int size = ArraySize(trades);
        int count = 0;
        
        for(int i = 0; i < size; i++) {
            if(trades[i].status == status) {
                ArrayResize(filteredTrades, count + 1);
                filteredTrades[count] = trades[i];
                count++;
            }
        }
        
        return count;
    }
    
    // 取消交易
    bool CancelTrade(ulong ticket) {
        for(int i = 0; i < ArraySize(trades); i++) {
            if(trades[i].ticket == ticket && trades[i].status == TRADE_STATUS_PENDING) {
                trades[i].status = TRADE_STATUS_CANCELLED;
                return true;
            }
        }
        return false;
    }
    
    // 清除交易历史
    void ClearHistory() {
        ArrayFree(trades);
    }
}; 